package com.sun.config;

import com.sun.enums.HttpEnum;
import com.sun.exception.BusinessException;
import com.sun.exception.SystemException;
import com.sun.pojo.vo.R;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.naming.AuthenticationException;
import javax.servlet.http.HttpServletRequest;
import java.nio.file.AccessDeniedException;

/**
 * @author SunRui
 * @description 异常处理类
 * @date 2024/10/14 11:22
 */
@RestControllerAdvice
public class GlobalException {

    @ExceptionHandler(SystemException.class)
    public R doSystemException(SystemException e){
        // 记录日志
        // 发送消息给运维
        // 发送邮件给开发人员
        // 发送异常给开发人员
        return R.fail(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(BusinessException.class)
    public R doBusinessException(BusinessException e){
        return R.fail(e.getCode(),e.getMessage());
    }


    /*
    400
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public R GlobalExceptionNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
        StringBuilder sb = new StringBuilder("接口："+request.getRequestURI()+" 校验失败:");
        for (FieldError fieldError : ex.getBindingResult().getFieldErrors()) {
            sb.append(fieldError.getField()).append("：").append(fieldError.getDefaultMessage()).append("。 ");
        }
        String msg = sb.toString();
        return R.fail(HttpEnum.BAD_REQUEST.getCode(), msg);
    }

    /*
    405
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) // 设置响应状态码
    public R handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException ex, HttpServletRequest request) {
        String errorMsg = "接口：" + request.getRequestURI() + " 请求的方法不被支持，请检查您的HTTP方法。";
        return R.fail(HttpEnum.BAD_METHOD.getCode(), errorMsg);
    }


    /*
    500
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 设置响应状态码为500
    public R handleAllExceptions(Exception ex, HttpServletRequest request) {
        // 构建基础错误信息
        String errorMsg = "接口：" + request.getRequestURI() + " 发生内部错误";
        // 可以考虑添加一个简化的异常描述，比如只使用异常的简单名称
        String simpleExceptionMsg = ex.getClass().getSimpleName(); // 获取异常类的简单名称
        // 将具体异常信息整合进错误信息中，但避免泄露敏感信息
        errorMsg += "，具体原因可能是：" + simpleExceptionMsg;
        return R.fail(HttpEnum.ERROR.getCode(), errorMsg);
    }

    /*
    415
     */
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    public R handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException ex, HttpServletRequest request) {
        String errorMsg = "接口：" + request.getRequestURI() + " 不支持的媒体类型，请检查Content-Type。";
        return R.fail(HttpEnum.UNSUPPORTED_TYPE.getCode(), errorMsg);
    }

    /*
    409
     */
    @ExceptionHandler(DataIntegrityViolationException.class)
    @ResponseStatus(HttpStatus.CONFLICT)
    public R handleDataIntegrityViolationException(DataIntegrityViolationException ex, HttpServletRequest request) {
        String errorMsg = "接口：" + request.getRequestURI() + " 数据冲突，操作无法完成。";
        return R.fail(HttpEnum.CONFLICT.getCode(), errorMsg);
    }

    /*
    404
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public R handleNotFoundException(NoHandlerFoundException ex, HttpServletRequest request) {
        String errorMsg = "接口：" + request.getRequestURI() + " 未找到。";
        return R.fail(HttpEnum.NOT_FOUND.getCode(), errorMsg);
    }

    /*
    403
     */
    @ExceptionHandler(AccessDeniedException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public R handleForbiddenException(AccessDeniedException ex, HttpServletRequest request) {
        String errorMsg = "接口：" + request.getRequestURI() + " 禁止访问，权限不足。";
        return R.fail(HttpEnum.FORBIDDEN.getCode(), errorMsg);
    }

    /*
    401
     */
    @ExceptionHandler(AuthenticationException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public R handleUnauthorizedException(AuthenticationException ex, HttpServletRequest request) {
        String errorMsg = "接口：" + request.getRequestURI() + " 未授权，请检查认证信息。";
        return R.fail(HttpEnum.UNAUTHORIZED.getCode(), errorMsg);
    }
}
